package com.fangcang.base.service.impl;

import com.fangcang.base.domain.ExchangeDO;
import com.fangcang.base.domain.ExchangeLogDO;
import com.fangcang.base.mapper.ExchangeLogMapper;
import com.fangcang.base.mapper.ExchangeMapper;
import com.fangcang.base.request.QueryExchangeDTO;
import com.fangcang.base.request.UpdateExchangeDTO;
import com.fangcang.base.response.ExchangeDTO;
import com.fangcang.base.response.ExchangeLogDTO;
import com.fangcang.base.service.ExchangeService;
import com.fangcang.common.ResponseDTO;
import com.fangcang.common.constant.InitData;
import com.fangcang.common.enums.CurrencyEnum;
import com.fangcang.common.enums.ErrorCodeEnum;
import com.fangcang.common.enums.ResultCodeEnum;
import com.fangcang.common.util.PropertyCopyUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ExchangeServiceImpl implements ExchangeService {

    @Autowired
    private ExchangeMapper exchangeMapper;

    @Autowired
    private ExchangeLogMapper exchangeLogMapper;

    @Override
    public void initExchange() {
        List<ExchangeDO> exchangeDOS = exchangeMapper.selectAll();
        Map<String, BigDecimal> merchantExchangeMap = new HashMap<>(8);
        if (CollectionUtils.isNotEmpty(exchangeDOS)) {
            for (ExchangeDO exchangeDO : exchangeDOS) {
                String key = exchangeDO.getMerchantCode() + "-" + exchangeDO.getSourceCurrency() + "-" + exchangeDO.getTargetCurrency();
                merchantExchangeMap.put(key, exchangeDO.getRate());
            }
        }
        InitData.merchantExchangeMap = merchantExchangeMap;
    }

    @Override
    public List<ExchangeDTO> queryExchange(QueryExchangeDTO requestDTO) {
        List<ExchangeDTO> exchangeDTOS = exchangeMapper.queryExchange(requestDTO);
        if (CollectionUtils.isNotEmpty(exchangeDTOS)) {
            for (ExchangeDTO exchangeDTO : exchangeDTOS) {
                exchangeDTO.setSourceCurrencyName(CurrencyEnum.getDescByValue(exchangeDTO.getSourceCurrency()));
                exchangeDTO.setTargetCurrencyName(CurrencyEnum.getDescByValue(exchangeDTO.getTargetCurrency()));
            }
        }
        return exchangeDTOS;
    }

    @Transactional
    @Override
    public ResponseDTO saveOrUpdateExchange(UpdateExchangeDTO updateExchangeDTO) {
        // 0. 参数校验
        if (updateExchangeDTO.getSourceCurrency().equals(updateExchangeDTO.getTargetCurrency())) {
            return new ResponseDTO(ResultCodeEnum.FAILURE.code, ErrorCodeEnum.INVALID_INPUTPARAM.errorCode, "不能录入相同币种汇率");
        }
        // 1. 保存或更新汇率
        ExchangeDO exchangeDO = PropertyCopyUtil.transfer(updateExchangeDTO, ExchangeDO.class);
        Date date = new Date();
        BigDecimal oldRate = BigDecimal.ZERO;
        if (exchangeDO.getId() == null) {
            // 检查是否存在
            Example example = new Example(ExchangeDO.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("sourceCurrency", updateExchangeDTO.getSourceCurrency());
            criteria.andEqualTo("targetCurrency", updateExchangeDTO.getTargetCurrency());
            int count = exchangeMapper.selectCountByExample(example);
            if (count > 0) {
                return new ResponseDTO(ResultCodeEnum.FAILURE.code, ErrorCodeEnum.INVALID_INPUTPARAM.errorCode, "录入的兑换汇率已存在，不能重复录入");
            }
            // 新增
            exchangeDO.setCreator(updateExchangeDTO.getOperator());
            exchangeDO.setCreateTime(date);
            exchangeDO.setModifier(updateExchangeDTO.getOperator());
            exchangeDO.setModifyTime(date);
            exchangeMapper.insert(exchangeDO);
        } else {
            ExchangeDO oldExchangeDO = exchangeMapper.selectByPrimaryKey(exchangeDO.getId());
            oldRate = oldExchangeDO.getRate();
            // 修改
            exchangeDO.setModifier(updateExchangeDTO.getOperator());
            exchangeDO.setModifyTime(date);
            exchangeMapper.updateByPrimaryKeySelective(exchangeDO);
        }

        // 2. 保存汇率变更日志
        ExchangeLogDO logDO = new ExchangeLogDO();
        logDO.setMerchantCode(updateExchangeDTO.getMerchantCode());
        logDO.setNewRate(updateExchangeDTO.getRate());
        logDO.setOldRate(oldRate);
        logDO.setSourceCurrency(updateExchangeDTO.getSourceCurrency());
        logDO.setTargetCurrency(updateExchangeDTO.getTargetCurrency());
        logDO.setCreator(updateExchangeDTO.getOperator());
        logDO.setCreateTime(new Date());
        exchangeLogMapper.insert(logDO);

        return new ResponseDTO(ResultCodeEnum.SUCCESS.code);
    }

    @Override
    public List<ExchangeLogDTO> queryExchangeLog(QueryExchangeDTO requestDTO) {
        return exchangeLogMapper.queryExchangeLog(requestDTO);
    }
}
